package com.muyu.danmo.service.impl;

import com.muyu.common.core.domain.Result;
import com.muyu.common.core.enums.VipEquity;
import com.muyu.common.core.utils.DateUtils;
import com.muyu.common.core.utils.StringUtils;
import com.muyu.common.security.utils.SecurityUtils;
import com.muyu.common.system.domain.LoginUser;
import com.muyu.danmo.domain.DanmoFontGenerate;
import com.muyu.danmo.domain.DanmoFontType;
import com.muyu.danmo.mapper.DanmoFontGenerateMapper;
import com.muyu.danmo.req.DanmoFamousCardReq;
import com.muyu.danmo.req.DanmoFontSingleReq;
import com.muyu.danmo.req.DanmoFontTypeReq;
import com.muyu.danmo.service.IDanmoFontGenerateService;


import com.muyu.remote.RemoteVipPerson;
import com.muyu.system.domain.DanmoVipRights;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 字体信息Service业务层处理
 *
 * @author yangle
 * @date 2024-09-14
 */
@Service
public class DanmoFontGenerateServiceImpl implements IDanmoFontGenerateService {
    private static final Logger log = LoggerFactory.getLogger(DanmoFontGenerateServiceImpl.class);
    @Autowired
    private DanmoFontGenerateMapper danmoFontGenerateMapper;

    /**
     * 查询字体信息
     *
     * @param id 字体信息主键
     * @return 字体信息
     */
    @Override
    public DanmoFontGenerate selectDanmoFontGenerateById(Long id) {
        return danmoFontGenerateMapper.selectDanmoFontGenerateById(id);
    }

    /**
     * 查询字体信息列表
     *
     * @param danmoFontGenerate 字体信息
     * @return 字体信息
     */
    @Override
    public List<DanmoFontGenerate> selectDanmoFontGenerateList(DanmoFontGenerate danmoFontGenerate) {
        return danmoFontGenerateMapper.selectDanmoFontGenerateList(danmoFontGenerate);
    }

    /**
     * 新增字体信息
     *
     * @param danmoFontGenerate 字体信息
     * @return 结果
     */
    @Transactional
    @Override
    public int insertDanmoFontGenerate(DanmoFontGenerate danmoFontGenerate) {
        danmoFontGenerate.setCreateTime(DateUtils.getNowDate());
        int rows = danmoFontGenerateMapper.insertDanmoFontGenerate(danmoFontGenerate);
        insertDanmoFontType(danmoFontGenerate);
        return rows;
    }

    /**
     * 修改字体信息
     *
     * @param danmoFontGenerate 字体信息
     * @return 结果
     */
    @Transactional
    @Override
    public int updateDanmoFontGenerate(DanmoFontGenerate danmoFontGenerate) {
        danmoFontGenerate.setUpdateTime(DateUtils.getNowDate());
        danmoFontGenerateMapper.deleteDanmoFontTypeById(danmoFontGenerate.getId());
        insertDanmoFontType(danmoFontGenerate);
        return danmoFontGenerateMapper.updateDanmoFontGenerate(danmoFontGenerate);
    }

    /**
     * 批量删除字体信息
     *
     * @param ids 需要删除的字体信息主键
     * @return 结果
     */
    @Transactional
    @Override
    public int deleteDanmoFontGenerateByIds(Long[] ids) {
        danmoFontGenerateMapper.deleteDanmoFontTypeByIds(ids);
        return danmoFontGenerateMapper.deleteDanmoFontGenerateByIds(ids);
    }

    /**
     * 删除字体信息信息
     *
     * @param id 字体信息主键
     * @return 结果
     */
    @Transactional
    @Override
    public int deleteDanmoFontGenerateById(Long id) {
        danmoFontGenerateMapper.deleteDanmoFontTypeById(id);
        return danmoFontGenerateMapper.deleteDanmoFontGenerateById(id);
    }


    /**
     * 新增字体类型信息
     *
     * @param danmoFontGenerate 字体信息对象
     */
    public void insertDanmoFontType(DanmoFontGenerate danmoFontGenerate) {
        List<DanmoFontType> danmoFontTypeList = danmoFontGenerate.getDanmoFontTypeList();
        Long id = danmoFontGenerate.getId();
        if (StringUtils.isNotNull(danmoFontTypeList)) {
            List<DanmoFontType> list = new ArrayList<DanmoFontType>();
            for (DanmoFontType danmoFontType : danmoFontTypeList) {
                danmoFontType.setId(id);
                list.add(danmoFontType);
            }
            if (list.size() > 0) {
                danmoFontGenerateMapper.batchDanmoFontType(list);
            }
        }
    }
    @Autowired
    private NamedParameterJdbcTemplate namedParameterJdbcTemplate;
    @Autowired
    private RemoteVipPerson remoteVipPerson;
    /**
     * 生成单个字体
     *
     * @param danmoFontSingleReq
     * @return
     */

    @Override
    public Result generate(DanmoFontSingleReq danmoFontSingleReq) {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        Long userid = loginUser.getUserid();
        List<DanmoVipRights> personRights = remoteVipPerson.getPersonRights(userid);
// 获取用户输入的字体列表
        List<String> font = danmoFontSingleReq.getFont();
        int size = font.size();

// 默认非会员限制为8个字
        int maxLength = 8;

// 检查是否有会员权限，并确定最大长度
        for (DanmoVipRights personRight : personRights) {
            if (personRight.getVipInfoId() == VipEquity.WORD_BOOK.getCode()) {
                // 单词本会员可以输入25个字
                maxLength = 500;
                break;
            } else if (personRight.getVipInfoId() == VipEquity.SEAL_WORD_BOOK.getCode()) {
                // 印章单词本会员可以输入8个字（与非会员相同，但逻辑上可能有其他权限）
                maxLength = 50;
                break;
            }
        }

// 检查字体长度是否超过限制
        if (size > maxLength) {
            return Result.error("请输入" + maxLength + "个字");
        }
        String tableName = determineTable(danmoFontSingleReq.getFontType());

            // 2. 执行批量查询操作，构建查询条件
            List<DanmoFontGenerate> result = fetchFromTableOne(tableName, danmoFontSingleReq);

            return Result.success(result);

    }
    private List<DanmoFontGenerate> fetchFromTableOne(String tableName, DanmoFontSingleReq danmoFontSingleReq) {
            List<DanmoFontGenerate> results = new ArrayList<>();
            List<String> fonts = danmoFontSingleReq.getFont();

            if (fonts == null || fonts.isEmpty()) {
                return results;
            }

            // 去重字体
            Set<String> uniqueFonts = new HashSet<>(fonts);

            // 1. 构建查询条件
            StringBuilder query = new StringBuilder()
                    .append("SELECT g.id, g.font, g.font_picture, g.font_type_id, ")
                    .append("g.font_name, g.author, f.font_type AS fontName, g.tarnstram, g.width, g.high, g.svg_url,g.vip ")
                    .append("FROM ").append(tableName).append(" g ")
                    .append("LEFT JOIN danmo_font_type f ON f.id = g.font_type_id ")
                    .append("WHERE g.font IN (:fonts) ");

            // 2. 添加 author 查询条件
            String author = danmoFontSingleReq.getAuthor();
            Map<String, Object> params = new HashMap<>();
            params.put("fonts", uniqueFonts);
            if (author != null && !author.isEmpty()) {
                query.append("AND g.author = :author ");
                params.put("author", author);
            }

            // 3. 执行查询
            List<DanmoFontGenerate> subResults = namedParameterJdbcTemplate.query(query.toString(), params, new RowMapper<DanmoFontGenerate>() {
                @Override
                public DanmoFontGenerate mapRow(ResultSet rs, int rowNum) throws SQLException {
                    DanmoFontGenerate fontInfo = new DanmoFontGenerate();
                    fontInfo.setId(rs.getLong("id"));
                    fontInfo.setFont(rs.getString("font"));
                    fontInfo.setFontPicture(rs.getString("font_picture"));
                    fontInfo.setFontTypeId(rs.getLong("font_type_id"));
                    fontInfo.setFontName(rs.getString("font_name"));
                    fontInfo.setAuthor(rs.getString("author"));
                    fontInfo.setFontTypeName(rs.getString("fontName"));
                    fontInfo.setTarnstram(rs.getLong("tarnstram"));
                    fontInfo.setWidth(rs.getString("width"));
                    fontInfo.setHigh(rs.getString("high"));
                    fontInfo.setSvgUrl(rs.getString("svg_url"));
                    fontInfo.setVip(rs.getString("vip"));
                    return fontInfo;
                }
            });



            // 后续映射逻辑保持不变
            Map<String, DanmoFontGenerate> resultMap = new LinkedHashMap<>();
            for (DanmoFontGenerate fontInfo : subResults) {
                String font = fontInfo.getFont();
                if (!resultMap.containsKey(font)) {
                    resultMap.put(font, fontInfo);
                } else {
//                log.warn("Duplicate font found: {}", font);
                }
            }

            // 5. 根据输入的字体顺序返回结果
            results = fonts.stream()
                    .map(font -> resultMap.getOrDefault(font, createEmptyFont(font)))
                    .collect(Collectors.toList());

            return results;
        }




    private String buildQuery(String tableName, String author) {
        // 动态构建SQL查询语句
        StringBuilder query = new StringBuilder()
                .append("SELECT g.id, g.font, g.font_picture, g.font_type_id,g.svg_url ")
                .append("g.font_name, g.author, f.font_type AS fontName, g.tarnstram, g.width, g.high ")
                .append("FROM ").append(tableName).append(" g ")
                .append("LEFT JOIN danmo_font_type f ON f.id = g.font_type_id ")
                .append("WHERE g.font IN (:fonts) ");

        // 如果有author条件，添加到查询条件中
        if (author != null && !author.isEmpty()) {
            query.append("AND g.author = :author ");
        }
        return query.toString();
    }

    private DanmoFontGenerate createEmptyFont(String font) {
        // 创建一个空的DanmoFontGenerate对象
        DanmoFontGenerate emptyFont = new DanmoFontGenerate();
        emptyFont.setFontTypeName("");
        emptyFont.setFont(font);
        emptyFont.setFontPicture("");
        emptyFont.setFontName("");
        emptyFont.setAuthor("");
        emptyFont.setWidth(String.valueOf(80));
        emptyFont.setHigh(String.valueOf(80));
        emptyFont.setSvgUrl("https://www.bjdmts.com/image/fonts/output_1748395740452.svg");
        emptyFont.setVip("");
        return emptyFont;
    }

    @Override
    public List<DanmoFontGenerate> selectFontType(DanmoFontTypeReq danmoFontTypeReq) {
        return danmoFontGenerateMapper.selectFontType(danmoFontTypeReq);
    }

    @Autowired
    private JdbcTemplate jdbcTemplate;

    /**
     * 查询某一个字体全部
     *
     * @param danmoFontSingleReq
     * @return
     */
    @Override
    public List<DanmoFontGenerate> queryFont(DanmoFontSingleReq danmoFontSingleReq) {
        // 1. 根据 fontType 确定查询的表
        String tableName = determineTable(danmoFontSingleReq.getFontType());
        if (tableName == null) {
            throw new IllegalArgumentException("Invalid font type provided.");
        }
        // 2. 执行分表查询操作，构建查询条件
        List<DanmoFontGenerate> result = fetchFromTable(tableName, danmoFontSingleReq);
        return result;
    }

    private String determineTable(Long fontType) {
        Map<Long, String> tableMap = new HashMap<>();
        tableMap.put(1L, "danmo_font_caoshu");
        tableMap.put(2L, "danmo_font_hangshu");
        tableMap.put(3L, "danmo_font_lishu");
        tableMap.put(5L, "danmo_font_kaishu");
        tableMap.put(6L, "danmo_font_xiaokai");
        tableMap.put(22L, "danmo_font_weibei");
        tableMap.put(23L, "danmo_font_hangcao");
        tableMap.put(24L, "danmo_font_zhangcao");
        tableMap.put(25L, "danmo_font_zhuanshu");

        return tableMap.getOrDefault(fontType, "danmo_font_generate");
    }

    private List<DanmoFontGenerate> fetchFromTable(String tableName, DanmoFontSingleReq danmoFontSingleReq) {
        StringBuilder query = new StringBuilder("SELECT g.id, g.font_picture, g.font_type_id, g.font_name, g.font, g.author,g.svg_url, f.font_type as fontName, g.tarnstram, g.width, g.high,g.vip ");
        query.append("FROM ").append(tableName).append(" g ");
        query.append("LEFT JOIN danmo_font_type f ON f.id = g.font_type_id WHERE 1=1");

        List<Object> params = new ArrayList<>();
        appendFontCondition(query, params, danmoFontSingleReq.getFont());
        appendAuthorCondition(query, params, danmoFontSingleReq.getAuthor());
        query.append(" LIMIT ? OFFSET ?");
        params.add(danmoFontSingleReq.getPageSize());               // 对应 LIMIT ?
        params.add((danmoFontSingleReq.getPageNum() - 1) * danmoFontSingleReq.getPageSize()); // 对应 OFFSET ?

        List<DanmoFontGenerate> results = jdbcTemplate.query(query.toString(), params.toArray(), this::mapRowToDanmoFontGenerate);

        // 按作者分组并处理VIP权限
        if (!results.isEmpty()) {
            // 按作者分组
            Map<String, List<DanmoFontGenerate>> authorGroups = new HashMap<>();
            for (DanmoFontGenerate font : results) {
                String author = font.getAuthor();
                authorGroups.computeIfAbsent(author, k -> new ArrayList<>()).add(font);
            }

            // 处理每个作者的VIP权限
            List<DanmoFontGenerate> processedResults = new ArrayList<>();
            for (List<DanmoFontGenerate> authorFonts : authorGroups.values()) {
                // 按ID排序，确保顺序一致
                authorFonts.sort(Comparator.comparing(DanmoFontGenerate::getId));

                // 第一个设为VIP=0，其余设为VIP=1
                for (int i = 0; i < authorFonts.size(); i++) {
                    DanmoFontGenerate font = authorFonts.get(i);
                    font.setVip(i == 0 ? "0" : "1");
                    processedResults.add(font);
                }
            }

            // 按作者排序
            processedResults.sort(Comparator.comparing(DanmoFontGenerate::getAuthor)
                    .thenComparing(DanmoFontGenerate::getId));

            return processedResults;
        }

        return results;
    }

    private void appendFontCondition(StringBuilder query, List<Object> params, List<String> fonts) {
        if (fonts != null && !fonts.isEmpty()) {
            query.append(" AND g.font IN (");
            for (int i = 0; i < fonts.size(); i++) {
                query.append("?");
                if (i < fonts.size() - 1) {
                    query.append(", ");
                }
            }
            query.append(")");
            params.addAll(fonts);
        }
    }

    private void appendAuthorCondition(StringBuilder query, List<Object> params, String author) {
        if (author != null && !author.isEmpty()) {
            query.append(" AND g.author = ?");
            params.add(author);
        }
    }

    private DanmoFontGenerate mapRowToDanmoFontGenerate(ResultSet rs, int rowNum) throws SQLException {
        DanmoFontGenerate fontInfo = new DanmoFontGenerate();
        fontInfo.setId(rs.getLong("id"));
        fontInfo.setFontPicture(rs.getString("font_picture"));
        fontInfo.setFontTypeId(rs.getLong("font_type_id"));
        fontInfo.setFont(rs.getString("font"));
        fontInfo.setAuthor(rs.getString("author"));
        fontInfo.setFontName(rs.getString("font_name"));
        fontInfo.setFontTypeName(rs.getString("fontName"));
        fontInfo.setTarnstram(rs.getLong("tarnstram"));
        fontInfo.setWidth(rs.getString("width"));
        fontInfo.setHigh(rs.getString("high"));
        fontInfo.setSvgUrl(rs.getString("svg_url"));
        fontInfo.setVip(rs.getString("vip"));


        return fontInfo;
    }

    /**
     * 查询名帖字库
     *
     * @param danmoFamousCardReq
     * @return
     */
    @Override
    public List<DanmoFontGenerate> queryFamousCard(DanmoFamousCardReq danmoFamousCardReq) {
        List<DanmoFontGenerate> list = new ArrayList<>();
        Set<String> fonts = new HashSet<>(danmoFamousCardReq.getFont());

        for (String font : fonts) {
            DanmoFontGenerate danmoFontGenerate = new DanmoFontGenerate();
            danmoFontGenerate.setFont(font);
            danmoFontGenerate.setAuthor(danmoFamousCardReq.getAuthor());
            danmoFontGenerate.setFontTypeId(danmoFamousCardReq.getFontTypeId());
            danmoFontGenerate.setFontName(danmoFamousCardReq.getWorkName());
            log.debug(danmoFontGenerate.toString());

            List<DanmoFontGenerate> danmoFontGenerates = danmoFontGenerateMapper.queryFamousCard(danmoFontGenerate);
            if (danmoFontGenerates.isEmpty()) {
                return null;
            }
            list.addAll(danmoFontGenerates);
        }

        return list;

    }
}
